/*
 *  Copyright (C) 2010 Jesus Navalon i Pastor <jnavalon at redhermes dot net>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * HDD_Features.java
 *
 * Created on 07/12/2010, 23:08:39
 */
package kuasar.plugin.vmcreator.gui.tooltasks.AddHost.devicesFeat;

import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.HashMap;
import javax.swing.tree.DefaultMutableTreeNode;
import kuasar.plugin.vmcreator.gui.tooltasks.AddHost.pn_SetFeatures;

/**
 *
 * @author Jesus Navalon i Pastor <jnavalon at redhermes dot net>
 */
public class Attributes extends kuasar.plugin.classMod.AbstractPanel {

    private pn_SetFeatures parent;
    private DefaultMutableTreeNode node;
    private boolean slots[];
    private boolean loading = false;
    private int device;

    /** Creates new form HDD_Features */
    public Attributes(DefaultMutableTreeNode node, boolean slots[], pn_SetFeatures parent) {
        this.node = node;
        this.slots = slots;
        this.parent = parent;
        Object data[] = (Object[]) node.getUserObject();
        device = (Integer) ((HashMap<String, Object>) data[2]).get("id");
        initComponents();
        txt_Image_Path.setVisible(false);
        Load((Integer) data[0], (HashMap<String, Object>) data[2]);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lbl_Slots = new javax.swing.JLabel();
        cmb_Slots = new javax.swing.JComboBox();
        lbl_Image = new javax.swing.JLabel();
        lbl_Image_Path = new javax.swing.JLabel();
        txt_Image_Path = new javax.swing.JTextField();
        ccb_Differencing = new javax.swing.JCheckBox();

        setOpaque(false);

        lbl_Slots.setForeground(new java.awt.Color(204, 204, 204));
        lbl_Slots.setText("Slot:");

        cmb_Slots.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "" }));
        cmb_Slots.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cmb_SlotsItemStateChanged(evt);
            }
        });

        lbl_Image.setForeground(new java.awt.Color(204, 204, 204));
        lbl_Image.setText("Hard Disk:");

        lbl_Image_Path.setText(" ");
        lbl_Image_Path.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                lbl_Image_PathMouseReleased(evt);
            }
        });

        txt_Image_Path.setText(" ");
        txt_Image_Path.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txt_Image_PathKeyReleased(evt);
            }
        });

        ccb_Differencing.setForeground(new java.awt.Color(204, 204, 204));
        ccb_Differencing.setText("Differencing Disks");
        ccb_Differencing.setOpaque(false);
        ccb_Differencing.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                ccb_DifferencingStateChanged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(30, 30, 30)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lbl_Image)
                    .addComponent(lbl_Slots))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(ccb_Differencing)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lbl_Image_Path, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txt_Image_Path, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE))
                    .addComponent(cmb_Slots, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lbl_Slots)
                    .addComponent(cmb_Slots, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lbl_Image)
                    .addComponent(lbl_Image_Path)
                    .addComponent(txt_Image_Path, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(ccb_Differencing)
                .addContainerGap(188, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void txt_Image_PathKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txt_Image_PathKeyReleased

        switch (evt.getKeyCode()) {
            case KeyEvent.VK_ENTER:
                if (txt_Image_Path.getText().toLowerCase().equals("empty")) {
                    saveHDD(null);
                    return;
                }
                if (txt_Image_Path.getText().trim().isEmpty()) {
                    if (device != pn_SetFeatures.HDD_DEVICE) {
                        saveHDD(null);
                        txt_Image_Path.setText("Empty");
                        lbl_Image_Path.setText("Empty");
                        return;
                    }
                }
                File file = new File(txt_Image_Path.getText());
                if (!file.exists()) {
                    parent.setInfo("File \"" + txt_Image_Path.getText() + "\" no exists");
                    return;
                }
                saveHDD(file);
                txt_Image_Path.setVisible(false);
                lbl_Image_Path.setVisible(true);
                break;
            case KeyEvent.VK_ESCAPE:
                txt_Image_Path.setText(lbl_Image_Path.getText());
                txt_Image_Path.setVisible(false);
                lbl_Image_Path.setVisible(true);
                break;
            case KeyEvent.VK_DELETE:
                if (device == pn_SetFeatures.HDD_DEVICE) {
                    return;
                }
                if (evt.isShiftDown()) {
                    txt_Image_Path.setText("Empty");
                    lbl_Image_Path.setText("Empty");
                    saveHDD(null);
                    txt_Image_Path.setVisible(false);
                    lbl_Image_Path.setVisible(true);
                }
                break;
        }
    }//GEN-LAST:event_txt_Image_PathKeyReleased

    private void lbl_Image_PathMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lbl_Image_PathMouseReleased

        if (evt.isShiftDown()) {
            txt_Image_Path.setVisible(true);
            lbl_Image_Path.setVisible(false);
        } else {
            File selectedFile = parent.selectHDD(device);
            if (selectedFile == null) {
                return;
            }
            lbl_Image_Path.setText(selectedFile.getAbsolutePath());
            txt_Image_Path.setText(lbl_Image_Path.getText());
            saveHDD(selectedFile);
        }
    }//GEN-LAST:event_lbl_Image_PathMouseReleased

    private void cmb_SlotsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cmb_SlotsItemStateChanged
        if (loading) {
            return;
        }
        if (evt.getStateChange() == ItemEvent.DESELECTED) {
            return;
        }
        saveSlots();
    }//GEN-LAST:event_cmb_SlotsItemStateChanged

    private void ccb_DifferencingStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_ccb_DifferencingStateChanged
        if (loading) {
            return;
        }
        switch (device) {
            case pn_SetFeatures.HDD_DEVICE:
                ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).put("diff", ccb_Differencing.isSelected());
                break;
            case pn_SetFeatures.DVD_DEVICE:
                ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).put("passthrough", ccb_Differencing.isSelected());
                break;
        }

    }//GEN-LAST:event_ccb_DifferencingStateChanged

    private void saveSlots() {
        int old = (Integer) ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).get("slot");
        slots[old] = false;
        int i = 0;
        for (int freeSlots = 0; freeSlots != cmb_Slots.getSelectedIndex() + 1; i++) {
            if (slots[i] == false) {
                freeSlots++;
            }
        }
        slots[i - 1] = true;
        ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).put("slot", i - 1);
        parent.replaceSlots((Integer) ((Object[]) node.getUserObject())[0], slots);
        parent.treeSort((DefaultMutableTreeNode) node);
    }

    private void saveHDD(File file) {
        ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).put("file", file);
        if (file == null) {
            ((Object[]) node.getUserObject())[1] = "Empty";
            lbl_Image_Path.setText("Empty");
            ccb_Differencing.setEnabled(false);
        } else {
            ((Object[]) node.getUserObject())[1] = file.getName();
            lbl_Image_Path.setText(file.getAbsolutePath());
            ccb_Differencing.setEnabled(true);
        }
    }

    private void Load(int model, HashMap<String, Object> map) {
        loading = true;
        File file = (File) map.get("file");
        String filePath;
        if (file == null) {
            filePath = "Empty";
        } else {
            filePath = file.getAbsolutePath();
        }
        lbl_Image_Path.setText(filePath);
        txt_Image_Path.setText(filePath);
        txt_Image_Path.setLocation(lbl_Image_Path.getLocation());
        int curslot = (Integer) map.get("slot");
        int selslot = 0;
        switch (device) {
            case pn_SetFeatures.HDD_DEVICE:
                ccb_Differencing.setSelected((Boolean) ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).get("diff"));
                lbl_Image.setText("Hard Disk");
                ccb_Differencing.setText("Differencing Disks");
                break;
            case pn_SetFeatures.DVD_DEVICE:
                ccb_Differencing.setSelected((Boolean) ((HashMap<String, Object>) ((Object[]) node.getUserObject())[2]).get("passthrough"));
                lbl_Image.setText("CD/DVD Disk");
                ccb_Differencing.setText("Passthrough");
                if(file==null){
                    ccb_Differencing.setSelected(false);
                    ccb_Differencing.setEnabled(false);
                }else{
                    ccb_Differencing.setEnabled(true);
                }
                break;
            case pn_SetFeatures.FLOPPY_DEVICE:
                ccb_Differencing.setVisible(false);
                lbl_Image.setText("Floppy Disk");
                break;
        }

        cmb_Slots.removeAllItems();

        for (int i = 0; i < slots.length; i++) {
            if (slots[i] == true) {
                if (curslot == i) {
                    selslot = cmb_Slots.getItemCount();
                    cmb_Slots.addItem(getSlotName(model, i));
                }
            } else {
                cmb_Slots.addItem(getSlotName(model, i));
            }
        }
        cmb_Slots.setSelectedItem(cmb_Slots.getItemAt(selslot));
        loading = false;
    }

    private String getSlotName(int module, int position) {
        String ideslotname[] = {"IDE Primary Master", "IDE Secondary Master", "IDE Primary Slave", "IDE Secondary Slave"};
        switch (module) {
            case pn_SetFeatures.IDE_MODULE:
                return ideslotname[position];
            case pn_SetFeatures.FLOPPY_MODULE:
                return "Floppy Device " + position;
            case pn_SetFeatures.SATA_MODULE:
                return "SATA Port " + position;
            case pn_SetFeatures.SCSI_MODULE:
                return "SCSI Port " + position;
            case pn_SetFeatures.SAS_MODULE:
                return "SAS Port " + position;
            default:
                return "";
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox ccb_Differencing;
    private javax.swing.JComboBox cmb_Slots;
    private javax.swing.JLabel lbl_Image;
    private javax.swing.JLabel lbl_Image_Path;
    private javax.swing.JLabel lbl_Slots;
    private javax.swing.JTextField txt_Image_Path;
    // End of variables declaration//GEN-END:variables
}
